package org.codehaus.activemq.spring;

import java.io.IOException;
import java.io.PrintStream;
import java.net.URL;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;

public class ActiveMQBeanDefinitionReader extends XmlBeanDefinitionReader {
	private String brokerName;

	public ActiveMQBeanDefinitionReader(BeanDefinitionRegistry beanDefinitionRegistry, String brokerName) {
		super(beanDefinitionRegistry);
		this.brokerName = brokerName;
		setEntityResolver(createEntityResolver());
	}

	public int registerBeanDefinitions(Document document, Resource resource) throws BeansException {
		try {
			Document newDocument = transformDocument(document);
			int a = super.registerBeanDefinitions(newDocument, resource);
			return a;
		} catch (Exception e) {
			throw new ConfigurationParseException(resource, e);
		}
	}

	public static Transformer createTransformer(Source source) throws TransformerConfigurationException {
		TransformerFactory factory = TransformerFactory.newInstance();
		Transformer transformer = factory.newTransformer(source);
		transformer.setURIResolver(new URIResolver() {
			public Source resolve(String href, String base) {
				System.out.println("Called with href:  " + href + " base: " + base);
				return null;
			}
		});
		return transformer;
	}

	public String getBrokerName() {
		return this.brokerName;
	}

	public void setBrokerName(String brokerName) {
		this.brokerName = brokerName;
	}

	protected Document transformDocument(Document document) throws IOException, TransformerException {
		Transformer transformer = createTransformer(createXslSource());
		transformer.setParameter("brokerName", getBrokerName());
		DOMResult result = new DOMResult();
		transformer.transform(new DOMSource(document), result);
		return (Document) result.getNode();
	}

	protected Source createXslSource() throws IOException {
		return new StreamSource(getXslResource().getInputStream(), getXslResource().getURL().toString());
	}

	protected ClassPathResource getXslResource() {
		return new ClassPathResource("org/codehaus/activemq/activemq-to-spring.xsl");
	}

	protected EntityResolver createEntityResolver() {
		return new ActiveMQDtdResolver();
	}
}